home *** CD-ROM | disk | FTP | other *** search
/ Mac Easy 2010 May / Mac Life Ubuntu.iso / casper / filesystem.squashfs / usr / src / linux-headers-2.6.28-15 / arch / um / include / asm / pgtable.h < prev    next >
Encoding:
C/C++ Source or Header  |  2008-12-24  |  9.7 KB  |  367 lines

  1. /* 
  2.  * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
  3.  * Copyright 2003 PathScale, Inc.
  4.  * Derived from include/asm-i386/pgtable.h
  5.  * Licensed under the GPL
  6.  */
  7.  
  8. #ifndef __UM_PGTABLE_H
  9. #define __UM_PGTABLE_H
  10.  
  11. #include <asm/fixmap.h>
  12.  
  13. #define _PAGE_PRESENT    0x001
  14. #define _PAGE_NEWPAGE    0x002
  15. #define _PAGE_NEWPROT    0x004
  16. #define _PAGE_RW    0x020
  17. #define _PAGE_USER    0x040
  18. #define _PAGE_ACCESSED    0x080
  19. #define _PAGE_DIRTY    0x100
  20. /* If _PAGE_PRESENT is clear, we use these: */
  21. #define _PAGE_FILE    0x008    /* nonlinear file mapping, saved PTE; unset:swap */
  22. #define _PAGE_PROTNONE    0x010    /* if the user mapped it with PROT_NONE;
  23.                    pte_present gives true */
  24.  
  25. #ifdef CONFIG_3_LEVEL_PGTABLES
  26. #include "asm/pgtable-3level.h"
  27. #else
  28. #include "asm/pgtable-2level.h"
  29. #endif
  30.  
  31. extern pgd_t swapper_pg_dir[PTRS_PER_PGD];
  32.  
  33. /* zero page used for uninitialized stuff */
  34. extern unsigned long *empty_zero_page;
  35.  
  36. #define pgtable_cache_init() do ; while (0)
  37.  
  38. /* Just any arbitrary offset to the start of the vmalloc VM area: the
  39.  * current 8MB value just means that there will be a 8MB "hole" after the
  40.  * physical memory until the kernel virtual memory starts.  That means that
  41.  * any out-of-bounds memory accesses will hopefully be caught.
  42.  * The vmalloc() routines leaves a hole of 4kB between each vmalloced
  43.  * area for the same reason. ;)
  44.  */
  45.  
  46. extern unsigned long end_iomem;
  47.  
  48. #define VMALLOC_OFFSET    (__va_space)
  49. #define VMALLOC_START ((end_iomem + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
  50. #define PKMAP_BASE ((FIXADDR_START - LAST_PKMAP * PAGE_SIZE) & PMD_MASK)
  51. #ifdef CONFIG_HIGHMEM
  52. # define VMALLOC_END    (PKMAP_BASE-2*PAGE_SIZE)
  53. #else
  54. # define VMALLOC_END    (FIXADDR_START-2*PAGE_SIZE)
  55. #endif
  56.  
  57. #define _PAGE_TABLE    (_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
  58. #define _KERNPG_TABLE    (_PAGE_PRESENT | _PAGE_RW | _PAGE_ACCESSED | _PAGE_DIRTY)
  59. #define _PAGE_CHG_MASK    (PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
  60.  
  61. #define PAGE_NONE    __pgprot(_PAGE_PROTNONE | _PAGE_ACCESSED)
  62. #define PAGE_SHARED    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
  63. #define PAGE_COPY    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
  64. #define PAGE_READONLY    __pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
  65. #define PAGE_KERNEL    __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
  66.  
  67. /*
  68.  * The i386 can't do page protection for execute, and considers that the same
  69.  * are read.
  70.  * Also, write permissions imply read permissions. This is the closest we can
  71.  * get..
  72.  */
  73. #define __P000    PAGE_NONE
  74. #define __P001    PAGE_READONLY
  75. #define __P010    PAGE_COPY
  76. #define __P011    PAGE_COPY
  77. #define __P100    PAGE_READONLY
  78. #define __P101    PAGE_READONLY
  79. #define __P110    PAGE_COPY
  80. #define __P111    PAGE_COPY
  81.  
  82. #define __S000    PAGE_NONE
  83. #define __S001    PAGE_READONLY
  84. #define __S010    PAGE_SHARED
  85. #define __S011    PAGE_SHARED
  86. #define __S100    PAGE_READONLY
  87. #define __S101    PAGE_READONLY
  88. #define __S110    PAGE_SHARED
  89. #define __S111    PAGE_SHARED
  90.  
  91. /*
  92.  * ZERO_PAGE is a global shared page that is always zero: used
  93.  * for zero-mapped memory areas etc..
  94.  */
  95. #define ZERO_PAGE(vaddr) virt_to_page(empty_zero_page)
  96.  
  97. #define pte_clear(mm,addr,xp) pte_set_val(*(xp), (phys_t) 0, __pgprot(_PAGE_NEWPAGE))
  98.  
  99. #define pmd_none(x)    (!((unsigned long)pmd_val(x) & ~_PAGE_NEWPAGE))
  100. #define    pmd_bad(x)    ((pmd_val(x) & (~PAGE_MASK & ~_PAGE_USER)) != _KERNPG_TABLE)
  101.  
  102. #define pmd_present(x)    (pmd_val(x) & _PAGE_PRESENT)
  103. #define pmd_clear(xp)    do { pmd_val(*(xp)) = _PAGE_NEWPAGE; } while (0)
  104.  
  105. #define pmd_newpage(x)  (pmd_val(x) & _PAGE_NEWPAGE)
  106. #define pmd_mkuptodate(x) (pmd_val(x) &= ~_PAGE_NEWPAGE)
  107.  
  108. #define pud_newpage(x)  (pud_val(x) & _PAGE_NEWPAGE)
  109. #define pud_mkuptodate(x) (pud_val(x) &= ~_PAGE_NEWPAGE)
  110.  
  111. #define pmd_page(pmd) phys_to_page(pmd_val(pmd) & PAGE_MASK)
  112.  
  113. #define pte_page(x) pfn_to_page(pte_pfn(x))
  114.  
  115. #define pte_present(x)    pte_get_bits(x, (_PAGE_PRESENT | _PAGE_PROTNONE))
  116.  
  117. /*
  118.  * =================================
  119.  * Flags checking section.
  120.  * =================================
  121.  */
  122.  
  123. static inline int pte_none(pte_t pte)
  124. {
  125.     return pte_is_zero(pte);
  126. }
  127.  
  128. /*
  129.  * The following only work if pte_present() is true.
  130.  * Undefined behaviour if not..
  131.  */
  132. static inline int pte_read(pte_t pte)
  133.     return((pte_get_bits(pte, _PAGE_USER)) &&
  134.            !(pte_get_bits(pte, _PAGE_PROTNONE)));
  135. }
  136.  
  137. static inline int pte_exec(pte_t pte){
  138.     return((pte_get_bits(pte, _PAGE_USER)) &&
  139.            !(pte_get_bits(pte, _PAGE_PROTNONE)));
  140. }
  141.  
  142. static inline int pte_write(pte_t pte)
  143. {
  144.     return((pte_get_bits(pte, _PAGE_RW)) &&
  145.            !(pte_get_bits(pte, _PAGE_PROTNONE)));
  146. }
  147.  
  148. /*
  149.  * The following only works if pte_present() is not true.
  150.  */
  151. static inline int pte_file(pte_t pte)
  152. {
  153.     return pte_get_bits(pte, _PAGE_FILE);
  154. }
  155.  
  156. static inline int pte_dirty(pte_t pte)
  157. {
  158.     return pte_get_bits(pte, _PAGE_DIRTY);
  159. }
  160.  
  161. static inline int pte_young(pte_t pte)
  162. {
  163.     return pte_get_bits(pte, _PAGE_ACCESSED);
  164. }
  165.  
  166. static inline int pte_newpage(pte_t pte)
  167. {
  168.     return pte_get_bits(pte, _PAGE_NEWPAGE);
  169. }
  170.  
  171. static inline int pte_newprot(pte_t pte)
  172.     return(pte_present(pte) && (pte_get_bits(pte, _PAGE_NEWPROT)));
  173. }
  174.  
  175. static inline int pte_special(pte_t pte)
  176. {
  177.     return 0;
  178. }
  179.  
  180. /*
  181.  * =================================
  182.  * Flags setting section.
  183.  * =================================
  184.  */
  185.  
  186. static inline pte_t pte_mknewprot(pte_t pte)
  187. {
  188.     pte_set_bits(pte, _PAGE_NEWPROT);
  189.     return(pte);
  190. }
  191.  
  192. static inline pte_t pte_mkclean(pte_t pte)
  193. {
  194.     pte_clear_bits(pte, _PAGE_DIRTY);
  195.     return(pte);
  196. }
  197.  
  198. static inline pte_t pte_mkold(pte_t pte)    
  199.     pte_clear_bits(pte, _PAGE_ACCESSED);
  200.     return(pte);
  201. }
  202.  
  203. static inline pte_t pte_wrprotect(pte_t pte)
  204.     pte_clear_bits(pte, _PAGE_RW);
  205.     return(pte_mknewprot(pte)); 
  206. }
  207.  
  208. static inline pte_t pte_mkread(pte_t pte)
  209.     pte_set_bits(pte, _PAGE_USER);
  210.     return(pte_mknewprot(pte)); 
  211. }
  212.  
  213. static inline pte_t pte_mkdirty(pte_t pte)
  214.     pte_set_bits(pte, _PAGE_DIRTY);
  215.     return(pte);
  216. }
  217.  
  218. static inline pte_t pte_mkyoung(pte_t pte)
  219. {
  220.     pte_set_bits(pte, _PAGE_ACCESSED);
  221.     return(pte);
  222. }
  223.  
  224. static inline pte_t pte_mkwrite(pte_t pte)    
  225. {
  226.     pte_set_bits(pte, _PAGE_RW);
  227.     return(pte_mknewprot(pte)); 
  228. }
  229.  
  230. static inline pte_t pte_mkuptodate(pte_t pte)    
  231. {
  232.     pte_clear_bits(pte, _PAGE_NEWPAGE);
  233.     if(pte_present(pte))
  234.         pte_clear_bits(pte, _PAGE_NEWPROT);
  235.     return(pte); 
  236. }
  237.  
  238. static inline pte_t pte_mknewpage(pte_t pte)
  239. {
  240.     pte_set_bits(pte, _PAGE_NEWPAGE);
  241.     return(pte);
  242. }
  243.  
  244. static inline pte_t pte_mkspecial(pte_t pte)
  245. {
  246.     return(pte);
  247. }
  248.  
  249. static inline void set_pte(pte_t *pteptr, pte_t pteval)
  250. {
  251.     pte_copy(*pteptr, pteval);
  252.  
  253.     /* If it's a swap entry, it needs to be marked _PAGE_NEWPAGE so
  254.      * fix_range knows to unmap it.  _PAGE_NEWPROT is specific to
  255.      * mapped pages.
  256.      */
  257.  
  258.     *pteptr = pte_mknewpage(*pteptr);
  259.     if(pte_present(*pteptr)) *pteptr = pte_mknewprot(*pteptr);
  260. }
  261. #define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
  262.  
  263. /*
  264.  * Conversion functions: convert a page and protection to a page entry,
  265.  * and a page entry and page directory to the page they refer to.
  266.  */
  267.  
  268. #define phys_to_page(phys) pfn_to_page(phys_to_pfn(phys))
  269. #define __virt_to_page(virt) phys_to_page(__pa(virt))
  270. #define page_to_phys(page) pfn_to_phys((pfn_t) page_to_pfn(page))
  271. #define virt_to_page(addr) __virt_to_page((const unsigned long) addr)
  272.  
  273. #define mk_pte(page, pgprot) \
  274.     ({ pte_t pte;                    \
  275.                             \
  276.     pte_set_val(pte, page_to_phys(page), (pgprot));    \
  277.     if (pte_present(pte))                \
  278.         pte_mknewprot(pte_mknewpage(pte));    \
  279.     pte;})
  280.  
  281. static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
  282. {
  283.     pte_set_val(pte, (pte_val(pte) & _PAGE_CHG_MASK), newprot);
  284.     return pte; 
  285. }
  286.  
  287. /*
  288.  * the pgd page can be thought of an array like this: pgd_t[PTRS_PER_PGD]
  289.  *
  290.  * this macro returns the index of the entry in the pgd page which would
  291.  * control the given virtual address
  292.  */
  293. #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD-1))
  294.  
  295. /*
  296.  * pgd_offset() returns a (pgd_t *)
  297.  * pgd_index() is used get the offset into the pgd page's array of pgd_t's;
  298.  */
  299. #define pgd_offset(mm, address) ((mm)->pgd+pgd_index(address))
  300.  
  301. /*
  302.  * a shortcut which implies the use of the kernel's pgd, instead
  303.  * of a process's
  304.  */
  305. #define pgd_offset_k(address) pgd_offset(&init_mm, address)
  306.  
  307. /*
  308.  * the pmd page can be thought of an array like this: pmd_t[PTRS_PER_PMD]
  309.  *
  310.  * this macro returns the index of the entry in the pmd page which would
  311.  * control the given virtual address
  312.  */
  313. #define pmd_page_vaddr(pmd) ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
  314. #define pmd_index(address) (((address) >> PMD_SHIFT) & (PTRS_PER_PMD-1))
  315.  
  316. #define pmd_page_vaddr(pmd) \
  317.     ((unsigned long) __va(pmd_val(pmd) & PAGE_MASK))
  318.  
  319. /*
  320.  * the pte page can be thought of an array like this: pte_t[PTRS_PER_PTE]
  321.  *
  322.  * this macro returns the index of the entry in the pte page which would
  323.  * control the given virtual address
  324.  */
  325. #define pte_index(address) (((address) >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
  326. #define pte_offset_kernel(dir, address) \
  327.     ((pte_t *) pmd_page_vaddr(*(dir)) +  pte_index(address))
  328. #define pte_offset_map(dir, address) \
  329.     ((pte_t *)page_address(pmd_page(*(dir))) + pte_index(address))
  330. #define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
  331. #define pte_unmap(pte) do { } while (0)
  332. #define pte_unmap_nested(pte) do { } while (0)
  333.  
  334. struct mm_struct;
  335. extern pte_t *virt_to_pte(struct mm_struct *mm, unsigned long addr);
  336.  
  337. #define update_mmu_cache(vma,address,pte) do ; while (0)
  338.  
  339. /* Encode and de-code a swap entry */
  340. #define __swp_type(x)            (((x).val >> 4) & 0x3f)
  341. #define __swp_offset(x)            ((x).val >> 11)
  342.  
  343. #define __swp_entry(type, offset) \
  344.     ((swp_entry_t) { ((type) << 4) | ((offset) << 11) })
  345. #define __pte_to_swp_entry(pte) \
  346.     ((swp_entry_t) { pte_val(pte_mkuptodate(pte)) })
  347. #define __swp_entry_to_pte(x)        ((pte_t) { (x).val })
  348.  
  349. #define kern_addr_valid(addr) (1)
  350.  
  351. #include <asm-generic/pgtable.h>
  352.  
  353. /* Clear a kernel PTE and flush it from the TLB */
  354. #define kpte_clear_flush(ptep, vaddr)        \
  355. do {                        \
  356.     pte_clear(&init_mm, (vaddr), (ptep));    \
  357.     __flush_tlb_one((vaddr));        \
  358. } while (0)
  359.  
  360. #endif
  361.